﻿#region << 文 件 说 明 >>
/*----------------------------------------------------------------
// 文件名称：YuQueClient
// 创 建 者：杨程
// 创建时间：2022/2/23 15:15:18
// 文件版本：V1.0.0
// ===============================================================
// 功能描述：
//		
//
//----------------------------------------------------------------*/
#endregion

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Vampirewal.Core.YuQueHelper.Model;

namespace Vampirewal.Core.YuQueHelper
{
    public interface IYuQueClient
    {
        /// <summary>
        /// 语雀个人设置的Token
        /// </summary>
        string Token { get;  }

        /// <summary>
        /// 语雀收集的用户标识
        /// </summary>
        string UserAgent { get;  }

        /// <summary>
        /// 语雀基础的api域名
        /// </summary>
        string baseUrl { get; }

        List<string> DocRepos { get;  }

        /// <summary>
        /// 添加知识库名称
        /// </summary>
        /// <param name="DocReposName"></param>
        void AddDocRepos(string DocReposName);

        /// <summary>
        /// 批量添加知识库名称
        /// </summary>
        /// <param name="DocReposNames"></param>
        void AddRangeDocRepos(List<string> DocReposNames);
        /// <summary>
        /// 设置基础配置
        /// </summary>
        /// <param name="token">语雀个人设置的skd</param>
        /// <param name="userAgent">语雀收集的用户标识</param>
        void SetConfig(string token, string userAgent = "Vampirewal.Core");

        /// <summary>
        /// 获取单篇文档的详细信息
        /// </summary>
        /// <param name="docRepo">文档所属的知识库 如：https://www.yuque.com/yuque/developer/repo 中的【yuque/developer】</param>
        /// <param name="slug">文档的路径 如：https://www.yuque.com/yuque/developer/repo 中的【repo】</param>
        /// <returns>文档的详细信息</returns>
        DocDetail GetDocDetail(string docRepo, string slug);


        /// <summary>
        /// 新增1条文档
        /// </summary>
        /// <param name="docRepo">文档所属的知识库 如：https://www.yuque.com/yuque/developer/repo 中的【yuque/developer】</param>
        /// <param name="data">Json数据</param>
        string PostDocDetail(string docRepo, string data);


        /// <summary>
        /// 获取知识库下的目录
        /// </summary>
        /// <param name="docRepo">文档所属的知识库 如：https://www.yuque.com/yuque/developer/repo 中的【yuque/developer】</param>
        /// <returns>目录信息</returns>
        List<Topic> GetRepoTopic(string docRepo);

        /// <summary>
        /// 获取知识库下的目录（树结构）
        /// </summary>
        /// <param name="docRepo">文档所属的知识库 如：https://www.yuque.com/yuque/developer/repo 中的【yuque/developer】</param>
        /// <returns>目录信息</returns>
        List<TopicTree> GetRepoTopicTree(string docRepo);
    }

    public sealed class YuQueClient: IYuQueClient
    {
        /// <summary>
        /// 语雀个人设置的skd
        /// </summary>
        public string Token { get;private set; }

        /// <summary>
        /// 语雀收集的用户标识
        /// </summary>
        public string UserAgent { get;private set; }

        /// <summary>
        /// 语雀基础的api域名
        /// </summary>
        public  string baseUrl { get; private set; } = "https://www.yuque.com/api/v2/";

        /// <summary>
        /// 设置基础配置
        /// </summary>
        /// <param name="token">语雀个人设置的skd</param>
        /// <param name="userAgent">语雀收集的用户标识</param>
        public void SetConfig(string token, string userAgent = "Vampirewal.Core")
        {
            Token = token;
            UserAgent = userAgent;
        }

        

        #region 知识库
        /// <summary>
        /// 知识库列表
        /// </summary>
        public List<string> DocRepos { get; private set; }
        /// <summary>
        /// 添加知识库名称
        /// </summary>
        /// <param name="DocReposName"></param>
        public void AddDocRepos(string DocReposName)
        {
            DocRepos.Add(DocReposName);
        }

        /// <summary>
        /// 批量添加知识库名称
        /// </summary>
        /// <param name="DocReposNames"></param>
        public void AddRangeDocRepos(List<string> DocReposNames)
        {
            DocRepos.AddRange(DocReposNames);
        } 
        #endregion


        /// <summary>
        /// 获取单篇文档的详细信息
        /// </summary>
        /// <param name="docRepo">文档所属的知识库 如：https://www.yuque.com/yuque/developer/repo 中的【yuque/developer】</param>
        /// <param name="slug">文档的路径 如：https://www.yuque.com/yuque/developer/repo 中的【repo】</param>
        /// <returns>文档的详细信息</returns>
        public DocDetail GetDocDetail(string docRepo, string slug)
        {
            string jsonStr = HttpWebClientHelper.HttpGet($"{baseUrl}repos/{docRepo}/docs/{slug}", Token, UserAgent);
            return JsonConvert.DeserializeObject<DocDetail>(jsonStr);
        }

        /// <summary>
        /// 新增1条文档
        /// </summary>
        /// <param name="docRepo">文档所属的知识库 如：https://www.yuque.com/yuque/developer/repo 中的【yuque/developer】</param>
        /// <param name="data">Json数据</param>
        public string PostDocDetail(string docRepo,string data)
        {
            return HttpWebClientHelper.HttpPost(data, $"{baseUrl}repos/{docRepo}/docs", Token, UserAgent);
        }

        /// <summary>
        /// 获取知识库下的目录
        /// </summary>
        /// <param name="docRepo">文档所属的知识库 如：https://www.yuque.com/yuque/developer/repo 中的【yuque/developer】</param>
        /// <returns>目录信息</returns>
        public List<Topic> GetRepoTopic(string docRepo)
        {
            string jsonStr = HttpWebClientHelper.HttpGet($"{baseUrl}repos/{docRepo}/toc", Token, UserAgent);
            return JsonConvert.DeserializeObject<TopicInfo>(jsonStr).Data;
        }

        /// <summary>
        /// 获取知识库下的目录（树结构）
        /// </summary>
        /// <param name="docRepo">文档所属的知识库 如：https://www.yuque.com/yuque/developer/repo 中的【yuque/developer】</param>
        /// <returns>目录信息</returns>
        public List<TopicTree> GetRepoTopicTree(string docRepo)
        {
            string jsonStr = HttpWebClientHelper.HttpGet($"{baseUrl}repos/{docRepo}/toc", Token, UserAgent);
            List<Topic> topicList = JsonConvert.DeserializeObject<TopicInfo>(jsonStr).Data;
            List<TopicTree> result = new List<TopicTree>();
            var firstList = topicList.Where(x => x.Level == 0);//第一级
            return ProcessTree(firstList, topicList);
        }

        /// <summary>
        /// 递归处理树结构
        /// </summary>
        /// <param name="child"></param>
        /// <param name="allList"></param>
        /// <returns></returns>
        private List<TopicTree> ProcessTree(IEnumerable<Topic> child, List<Topic> allList)
        {
            List<TopicTree> result = new List<TopicTree>();

            foreach (Topic item in child)
            {
                TopicTree topicTree = item.ToEntity();
                var childList = allList.Where(x => x.Parent_uuid == item.Uuid);
                if (childList.Count() > 0)
                {
                    topicTree.Child = ProcessTree(childList, allList);
                }
                result.Add(topicTree);
            }

            return result;
        }

    }

    internal static class TopicExtension
    {
        internal static TopicTree ToEntity(this Topic topic)
        {
            TopicTree result = new TopicTree
            {
                Child = new List<TopicTree>(),
                Child_uuid = topic.Child_uuid,
                Doc_id = topic.Doc_id,
                Id = topic.Id,
                Level = topic.Level,
                Open_window = topic.Open_window,
                Parent_uuid = topic.Parent_uuid,
                Prev_Uuid = topic.Prev_Uuid,
                Sibling_uuid = topic.Sibling_uuid,
                Title = topic.Title,
                Type = topic.Type,
                Url = topic.Url,
                Uuid = topic.Uuid,
                Visible = topic.Visible
            };

            return result;
        }
    }
}
